package il.ac.mta.javaweb.ex1.logic.players;

import il.ac.mta.javaweb.ex1.logic.BattleShip;
import il.ac.mta.javaweb.ex1.logic.ShipDirection;
import il.ac.mta.javaweb.ex1.logic.grids.BattleShipsGrid;
import il.ac.mta.javaweb.ex1.logic.grids.GridBase;
import il.ac.mta.javaweb.ex1.logic.grids.MarkingGrid;

import java.awt.Point;
import java.util.List;
import java.util.Random;

public class ComputerPlayer extends PlayerBase
{
	private static final String pcPlayerNamePattern = "PC Player %1d";
	private static int pcPlayerCounter = 1;

	public ComputerPlayer()
	{
		initRandomOwnGrid();
		this.setName(String.format(pcPlayerNamePattern, pcPlayerCounter++));
	}

	private void initRandomOwnGrid()
	{
		BattleShipsGrid grid = new BattleShipsGrid();
		this.setOwnGrid(grid);

		RandomlyCreateAndPositionShipsOfLength(BattleShipsGrid.TWO,
				BattleShipsGrid.MAX_ALLOWED_SHIPS_SIZE_TWO);
		RandomlyCreateAndPositionShipsOfLength(BattleShipsGrid.THREE,
				BattleShipsGrid.MAX_ALLOWED_SHIPS_SIZE_THREE);
		RandomlyCreateAndPositionShipsOfLength(BattleShipsGrid.FOUR,
				BattleShipsGrid.MAX_ALLOWED_SHIPS_SIZE_FOUR);
		RandomlyCreateAndPositionShipsOfLength(BattleShipsGrid.FIVE,
				BattleShipsGrid.MAX_ALLOWED_SHIPS_SIZE_FIVE);
	}

	private void RandomlyCreateAndPositionShipsOfLength(int length, int maxAllowedShipsForLength)
	{
		boolean cantSetShipAtChosenPosition;
		for (int i = 0; i < maxAllowedShipsForLength; ++i)
		{
			cantSetShipAtChosenPosition = true;			
			BattleShip ship = null;
			ShipDirection direction;

			while (cantSetShipAtChosenPosition)
			{
				direction = getRandomValidDirection();
				ship = new BattleShip(length, getRandomValidPoint(), direction);

				if (this.getOwnGrid().trySetShip(ship))
				{
					cantSetShipAtChosenPosition = false;
				}
			}
		}
	}

	private ShipDirection getRandomValidDirection()
	{
		int random = new Random().nextInt(2);

		if (random == 0)
		{
			return ShipDirection.HORIZONTAL;
		}
		else
		{
			return ShipDirection.VERTICAL;
		}
	}

	private Point getRandomValidPoint()
	{
		int x = new Random().nextInt(GridBase.WIDTH);
		int y = new Random().nextInt(GridBase.HEIGHT);

		return new Point(x, y);
	}

	private MarkingGrid getRandomMarkingGridToAttack()
	{
		List<MarkingGrid> markingGrids = this.getEnemiesMarkingGrids();

		for (MarkingGrid grid : markingGrids)
		{
			if (grid.getPlayer().getOwnGrid().allShipsSunk())
			{
				this.getEnemiesMarkingGrids().remove(grid);
			}
		}

		return this.getEnemiesMarkingGrids().get(
				new Random().nextInt(this.getEnemiesMarkingGrids().size()));
	}

	public MarkingGrid playTurn()
	{
		Random random = new Random();
		Point positionToAttack;
		
		MarkingGrid enemyMarkingGrid = getRandomMarkingGridToAttack();
		BattleShipsGrid enemyGrid = enemyMarkingGrid.getPlayer().getOwnGrid();
			
		do
		{
			positionToAttack = new Point(random.nextInt(GridBase.WIDTH),
					random.nextInt(GridBase.HEIGHT));
		}
		while ((enemyMarkingGrid.isSelectedAt(positionToAttack) || isHitAtPoint(positionToAttack,
				enemyMarkingGrid)) && !enemyGrid.allShipsSunk());

		enemyGrid.bomb(positionToAttack);
		enemyMarkingGrid.markAsBombed(positionToAttack);
		enemyMarkingGrid.mark(positionToAttack);

		lastAttackedPosition = positionToAttack;
		return enemyMarkingGrid;
	}

	private boolean isHitAtPoint(Point positionToAttack, MarkingGrid enemyMarkingGrid)
	{
		return enemyMarkingGrid.getPlayer().getOwnGrid().isHitAtPoint(positionToAttack);
	}

	Point lastAttackedPosition = null;

	public Point getLastAttackedPosition()
	{
		return lastAttackedPosition;
	}

}
